import 'dart:convert';
import 'dart:io';

import 'package:archive/archive_io.dart';
import 'package:dio/dio.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:mmkv/mmkv.dart';
import 'package:path/path.dart' as path;
import 'package:path_provider/path_provider.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:videoplayer/features/room_list/entity/room_bean.dart';

import '../../../utils/file_reader.dart';
import '../../../utils/navigation_util.dart';
import '../datasources/video_tag_repository_impl.dart';
import '../entity/video_bean.dart';
import '../entity/video_tag_bean.dart';
import '../intent/video_tag_state.dart';

class VideoTagViewModel extends StateNotifier<VideoTagState> {
  final VideoTagRepositoryImpl repositoryImpl;

  VideoTagViewModel(this.repositoryImpl) : super(VideoTagState());

  void initData(String json) {
    ///从本地缓存中获取数据
    ///   如果是空的,联网下载压缩包
    ///       下载完成解压数据
    ///           读取所有数据,根据tag进行分类
    ///               显示类别
    ///   如果不是空的根据数据进行列表显示

    Map<String, dynamic> map = jsonDecode(json);
    RoomBean mRoomBean = RoomBean.fromJson(map);
    state = state.copyWith(intentData: mRoomBean);
    String? mJson = MMKV.defaultMMKV().decodeString(state.intentData!.tag);
    if (mJson == null || mJson.isEmpty) {
      //说明没有缓存过这个房间的数据,则正常联网请求,并缓存数据
      print('说明没有缓存过这个房间的数据,则正常联网请求,并缓存数据');
      MMKV.defaultMMKV().encodeString(state.intentData!.tag, json);
      _downloadZip(state.intentData!.roomUrl);
    } else {
      //缓存过数据根据缓存的数据显示
      print('缓存过数据根据缓存的数据显示');
      RoomBean saveData = RoomBean.fromJson(jsonDecode(mJson));
      if (mRoomBean.timeStamp == saveData.timeStamp) {
        //如果时间戳一样说明不用更新
        String? roomUiListJson = MMKV.defaultMMKV().decodeString(state.intentData!.roomUrl);
        if (roomUiListJson == null || roomUiListJson.isEmpty) {
          MMKV.defaultMMKV().removeValue(state.intentData!.tag);
          initData(json);
        } else {
          List<dynamic> jsonList = jsonDecode(roomUiListJson!);
          List<VideoTagBean> videoList = jsonList.map((jsonItem) => VideoTagBean.fromJson(jsonItem as Map<String, dynamic>)).toList();
          state = state.copyWith(roomUiList: videoList);
        }
      } else {
        MMKV.defaultMMKV().encodeString(state.intentData!.tag, json);
        _downloadZip(state.intentData!.roomUrl);
      }
    }
  }

  Future<bool> _requestStoragePermission() async {
    if (Platform.isAndroid) {
      // Android 13+ 使用新的权限
      if (await Permission.storage.request().isGranted || await Permission.manageExternalStorage.request().isGranted) {
        return true;
      }
      // 对于较低版本的Android
      if (await Permission.storage.request().isGranted) {
        return true;
      }
      return false;
    }
    return true; // iOS不需要存储权限
  }

  Future<String> _getDownloadPath() async {
    Directory? directory;

    if (Platform.isAndroid) {
      // 获取外部存储的Downloads目录
      directory = Directory('/storage/emulated/0/Download');
      if (!directory.existsSync()) {
        // 如果Downloads目录不存在，使用应用的外部存储目录
        directory = await getExternalStorageDirectory();
      }
    } else {
      // iOS使用应用文档目录
      directory = await getApplicationDocumentsDirectory();
    }

    return directory?.path ?? '';
  }

  // 方法1: 使用Uri.parse() - 推荐方法
  String _getFileNameFromUrl(String url) {
    Uri uri = Uri.parse(url);
    return uri.pathSegments.last;
  }

  Future<void> _downloadZip(String url) async {
    // 请求存储权限
    if (!await _requestStoragePermission()) {
      state = state.copyWith(pageState: '存储权限被拒绝');
      return;
    }
    try {
      state = state.copyWith(pageState: '准备下载...', progress: 0.0);
      // 获取下载路径
      String downloadDir = await _getDownloadPath();
      String fileName = _getFileNameFromUrl(url);
      String savePath = '$downloadDir/$fileName';
      state = state.copyWith(pageState: '开始下载...', downloadPath: savePath);
      await repositoryImpl.downloadZip(url, savePath, (received, total) {
        if (total != -1) {
          state = state.copyWith(pageState: '下载中... ${(received / 1024 / 1024).toStringAsFixed(1)}MB / ${(total / 1024 / 1024).toStringAsFixed(1)}MB', progress: received / total);
        }
      });
      state = state.copyWith(pageState: '下载完成！正在解压');
      _extractFiles(savePath);
    } on DioException catch (e) {
      state = state.copyWith(pageState: '下载失败: ${_getDioErrorMessage(e)}');
    } catch (e) {
      state = state.copyWith(pageState: '下载失败: $e');
    }
  }

  String _getDioErrorMessage(DioException e) {
    switch (e.type) {
      case DioExceptionType.connectionTimeout:
        return '连接超时';
      case DioExceptionType.sendTimeout:
        return '发送超时';
      case DioExceptionType.receiveTimeout:
        return '接收超时';
      case DioExceptionType.connectionError:
        return '连接错误';
      case DioExceptionType.badResponse:
        return '服务器响应错误: ${e.response?.statusCode}';
      case DioExceptionType.cancel:
        return '下载已取消';
      default:
        return e.message ?? '未知错误';
    }
  }

  // 方法1: 基础转换函数
  List<VideoBean> parseVideoList(String jsonString) {
    List<dynamic> jsonList = json.decode(jsonString);
    List<VideoBean> videoList = jsonList.map((jsonItem) => VideoBean.fromJson(jsonItem as Map<String, dynamic>)).toList();
    return videoList;
  }

  ///json字符串转换成List
  Future<List<VideoBean>> _parseVideoListAsync(String jsonString) async {
    return Future.delayed(Duration(milliseconds: 100), () {
      return parseVideoList(jsonString);
    });
  }

  ///提取文件
  Future<void> _extractFiles(String apkPath) async {
    print('删除文件');
    String jsonFile = apkPath.replaceAll(".zip", ".json");
    print(apkPath);
    print(jsonFile);
    print('*********************');
    String directoryPath = path.dirname(apkPath);
    extractFileToDisk(apkPath, directoryPath);
    state = state.copyWith(pageState: '解压完成,正在分类');
    String json = await FileReader.readDownloadFile(jsonFile);
    List<VideoBean> asyncVideoList = await _parseVideoListAsync(json);
    json = "";
    List<String> videoTag = [];
    List<VideoTagBean> roomList = [];
    List<VideoBean> videoList = [];
    for (VideoBean video in asyncVideoList) {
      if (!videoTag.contains(video.tags)) {
        videoTag.add(video.tags);
      }
    }
    for (String mTag in videoTag) {
      int mId = 1;
      if (videoList.isNotEmpty) {
        videoList.clear();
      }
      for (VideoBean mData in asyncVideoList) {
        if (mTag == mData.tags) {
          mData.id = mId;
          videoList.add(mData);
          mId += 1;
        }
      }
      roomList.add(VideoTagBean(name: state.intentData!.roomUrl + mTag, tag: mTag));
      MMKV.defaultMMKV().encodeString(state.intentData!.roomUrl + mTag, jsonEncode(videoList));
    }
    MMKV.defaultMMKV().encodeString(state.intentData!.roomUrl, jsonEncode(roomList));
    state = state.copyWith(roomUiList: roomList);
    videoTag.clear();
    videoList.clear();
    //删除下载的文件
    final file = File(apkPath);
    if (file.existsSync()) {
      await file.delete();
      print('文件删除成功');
    } else {
      print('文件不存在');
    }
    final file2 = File(jsonFile);
    if (file2.existsSync()) {
      await file2.delete();
      print('文件删除成功');
    } else {
      print('文件不存在');
    }
    state = state.copyWith(pageState: '');
  }

  void goNextPage(String json) {
    navigationUtil.goVideoListPage(json);
  }

  @override
  void dispose() {
    super.dispose();
    print('清空数据123');
  }
}
